package star.cloud.asme.person.ndePersonOperationRecord;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.file.fileInfo.FileInfo;
import star.cloud.asme.base.file.fileInfo.FileInfoMapper;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;
import star.cloud.asme.base.utils.ObjectsUtil;
import star.cloud.asme.system.user.User;
import star.cloud.asme.system.user.UserMapper;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

@Service
@Slf4j
@RequiredArgsConstructor
public class NdePersonOperationRecordServiceImpl extends IBaseServiceImpl<NdePersonOperationRecordMapper, NdePersonOperationRecord> implements NdePersonOperationRecordService {

    private final NdePersonOperationRecordMapper ndePersonOperationRecordMapper;
    private final UserMapper userMapper;
    private final FileInfoMapper fileInfoMapper;

    @Override
    public Result<NdePersonOperationRecord> getOneByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<NdePersonOperationRecord> queryWrapper = new LambdaQueryWrapper<>();

        switch (columnName) {
            case "id" -> queryWrapper.eq(NdePersonOperationRecord::getId, columnValue);
            case "username" -> queryWrapper.eq(NdePersonOperationRecord::getUsername, columnValue);
        }

        NdePersonOperationRecord ndePersonOperationRecord = ndePersonOperationRecordMapper.selectOne(queryWrapper);
        User user = userMapper.selectOneByUsername(ndePersonOperationRecord.getUsername());

        setCreatorAndUpdater(ndePersonOperationRecord);
        ndePersonOperationRecord.setUser(user);
        return Result.ok(ndePersonOperationRecord);
    }

    @Override
    public Result<List<NdePersonOperationRecord>> getListByCondition(String columnName, Object columnValue) {
        LambdaQueryWrapper<NdePersonOperationRecord> queryWrapper = new LambdaQueryWrapper<>();
        List<NdePersonOperationRecord> asmePersonInfoList = ndePersonOperationRecordMapper.selectList(queryWrapper);
        return Result.ok(asmePersonInfoList);
    }

    @Override
    public Result<List<NdePersonOperationRecord>> getListByConditions(NdePersonOperationRecord conditions) {
        LambdaQueryWrapper<NdePersonOperationRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getUsername()), NdePersonOperationRecord::getUsername, conditions.getUsername());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getMethod()), NdePersonOperationRecord::getMethod, conditions.getMethod());
        queryWrapper.orderByAsc(NdePersonOperationRecord::getUsername);
        queryWrapper.orderByAsc(NdePersonOperationRecord::getMethod);
        queryWrapper.orderByDesc(NdePersonOperationRecord::getOperationDate);
        List<NdePersonOperationRecord> ndePersonOperationRecords = ndePersonOperationRecordMapper.selectList(queryWrapper);
        ndePersonOperationRecords.forEach(ndePersonOperationRecord -> {
            FileInfo fileInfo = fileInfoMapper.selectOneByKeyWord(ndePersonOperationRecord.getAttachmentUuid());
            if (Objects.nonNull(fileInfo)) {
                ndePersonOperationRecord.setAttachmentUrl(fileInfo.getUrl());
            }
        });
        return Result.ok(ndePersonOperationRecords);
    }

    @Override
    public Result<IPage<NdePersonOperationRecord>> getListByConditionsWithPage(NdePersonOperationRecord conditions) {
        IPage<NdePersonOperationRecord> ipage = new Page<>(conditions.getCurrentPage(), conditions.getPageSize());
        LambdaQueryWrapper<NdePersonOperationRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getUsername()), NdePersonOperationRecord::getUsername, conditions.getUsername());
        queryWrapper.eq(ObjectsUtil.noNullAndEmpty(conditions.getMethod()), NdePersonOperationRecord::getMethod, conditions.getMethod());
        queryWrapper.ge(ObjectsUtil.noNullAndEmpty(conditions.getStartDate()), NdePersonOperationRecord::getOperationDate, conditions.getStartDate());
        queryWrapper.likeLeft(ObjectsUtil.noNullAndEmpty(conditions.getYear()), NdePersonOperationRecord::getOperationDate, conditions.getYear() + "%");
        queryWrapper.orderByAsc(NdePersonOperationRecord::getUsername);
        queryWrapper.orderByAsc(NdePersonOperationRecord::getMethod);
        queryWrapper.orderByDesc(NdePersonOperationRecord::getOperationDate);
        ndePersonOperationRecordMapper.selectPage(ipage, queryWrapper);
        setCreatorAndUpdater(ipage);
        ipage.getRecords().forEach(ndePersonOperationRecord -> {
            setCreatorAndUpdater(ndePersonOperationRecord);
            ndePersonOperationRecord.setUser(userMapper.selectOneByUsername(ndePersonOperationRecord.getUsername()));
            FileInfo fileInfo = fileInfoMapper.selectOneByKeyWord(ndePersonOperationRecord.getAttachmentUuid());
            if (fileInfo != null) {
                ndePersonOperationRecord.setAttachmentUrl(fileInfo.getUrl());
            }
        });
        return Result.ok(ipage);
    }

    @Override
    public Result<NdePersonOperationRecord> insertOne(NdePersonOperationRecord entity) {
        if (checkRepeat(entity)) {
            return Result.error(entity).msg("该时间所在半年已经存在连续操作记录。");
        }
        User user = userMapper.selectOneByUsername(entity.getUsername());
        entity.setName(user.getName());
        entity.setWorkNo(user.getWorkNo());
        entity.setAttachmentUuid(UUID.randomUUID().toString());
        int inserted = ndePersonOperationRecordMapper.insert(entity);
        return inserted > 0 ? Result.ok(entity) : Result.error(entity);
    }

    @Override
    public Result<NdePersonOperationRecord> updateOne(NdePersonOperationRecord entity) {
        if (checkRepeat(entity)) {
            return Result.error(entity).msg("该时间所在半年已经存在连续操作记录。");
        }
        User user = userMapper.selectOneByUsername(entity.getUsername());
        setVersion(entity);
        ndePersonOperationRecordMapper.updateById(entity);
        setCreatorAndUpdater(entity);
        entity.setUser(user);
        return Result.ok(entity);
    }

    private Boolean checkRepeat(NdePersonOperationRecord ndePersonOperationRecord) {
        LocalDate operationDate = ndePersonOperationRecord.getOperationDate();
        int monthValue = operationDate.getMonthValue();
        int monthFrom = monthValue < 7 ? 1 : 6;
        int monthTo = monthValue < 7 ? 7 : 12;
        int dayTo = monthValue < 7 ? 30 : 31;
        LocalDate localDateFrom = LocalDate.of(operationDate.getYear(), monthFrom, 1);
        LocalDate localDateTo = LocalDate.of(operationDate.getYear(), monthTo, dayTo);
        LambdaQueryWrapper<NdePersonOperationRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NdePersonOperationRecord::getUsername, ndePersonOperationRecord.getUsername());
        queryWrapper.eq(NdePersonOperationRecord::getMethod, ndePersonOperationRecord.getMethod());
        queryWrapper.between(NdePersonOperationRecord::getOperationDate, localDateFrom, localDateTo);
        return ndePersonOperationRecordMapper.selectCount(queryWrapper) > 0;
    }


}
